﻿/*****************************************************************
 * Copyright (C) Newegg Corporation. All rights reserved.
 * 
 * Author       :  Bill Li (Bill.S.Li@newegg.com)
 * Create Date  :  
 * Usage        :  
 *
 * RevisionHistory
 * Date         Author               Description
 * 
*****************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Xml;
using Framework;
using System.Text.RegularExpressions;

namespace TemplateEngine
{
    internal sealed class TemplateNode
    {
        private static Regex s_attrReg = new Regex("[\\s]+[a-zA-Z]+=(\"[^<>]*\"|'[^<>]*')", RegexOptions.Compiled);

        private NameValueCollection _attributes;

        private ITranslate _translate;

        private string _outStr;

        private string _innerStr;

        private TemplateDocument _document;

        private TemplateNode _root;

        private string _result = string.Empty;

        private string _commandStr;

        private TemplateNode _parent;

        private List<TemplateNode> _clidren;

        private Guid _uid;

        private bool _isResolved;

        internal string startNode;
        internal string endNode;
        internal int startNodeIdx;
        internal int endNodeIdx;

        public NameValueCollection Attributes
        {
            get { return _attributes; }
        }

        /// <summary>
        /// 是否已经解释完成
        /// </summary>
        public bool IsResolved
        {
            get { return _isResolved; }
            set { _isResolved = value; }
        }

        public TemplateDocument Document
        {
            get { return _document; }
            set { _document = value; }
        }

        /// <summary>
        /// 获取节点翻译接口
        /// </summary>
        internal ITranslate Translate
        {
            get { return _translate; }
        }

        /// <summary>
        /// 获取节点内数据
        /// </summary>
        public string InnerStr
        {
            get { return _innerStr; }
        }

        /// <summary>
        /// 结果字符串模板
        /// </summary>
        internal string ResultStr
        {
            get
            {
                return this._result;
            }
        }

        /// <summary>
        /// 获取或设置父节点
        /// </summary>
        internal TemplateNode Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }

        public Guid NodeGuid
        {
            get { return _uid; }
        }

        /// <summary>
        /// 获取或设置命令字符串
        /// </summary>
        internal string CommandStr
        {
            get { return _commandStr; }
            set { _commandStr = value; }
        }

        /// <summary>
        /// 获取或设置节点属于的文档
        /// </summary>
        internal TemplateNode Root
        {
            get { return _root; }
            set { _root = value; }
        }

        /// <summary>
        /// 获取节点集合
        /// </summary>
        public List<TemplateNode> Nodes
        {
            get
            {
                if (_clidren == null)
                {
                    _clidren = new List<TemplateNode>();
                }

                return _clidren;
            }
        }

        internal TemplateNode()
        {
            this._uid = Guid.NewGuid();
            this._attributes = new NameValueCollection();
        }

        /// <summary>
        /// 节点初始化方法
        /// </summary>
        internal void Initialize()
        {
            if (string.IsNullOrEmpty(this.startNode) || string.IsNullOrEmpty(this.endNode))
            {
                Exception ex = new ArgumentNullException("初始化异常，错误出现在解析函数中");
                TemplateLogger.Error(ex);
                throw ex;
            }

            // 如果开始索引号和结束索引号一致，则说明标签本身属于自动关闭标签
            if (this.startNodeIdx != this.endNodeIdx)
            {
                int len = this.endNodeIdx + this.endNode.Length - this.startNodeIdx;
                this._outStr = this.Document.Body.Substring(this.startNodeIdx, len);
                this._innerStr = this.Document.Body.Substring(this.startNodeIdx + this.startNode.Length, len - this.startNode.Length - this.endNode.Length);
            }
            else
            {
                this._innerStr = string.Empty;
                this._outStr = this.Document.Body.Substring(this.startNodeIdx, this.startNode.Length);
            }

            // 获取翻译对象
            this._translate = TranslateManager.GetTranslate(this.CommandStr);

            // 填充属性
            string tagStr = this.startNode;
            tagStr = tagStr.Replace("/>", string.Empty);
            tagStr = tagStr.Replace(">", string.Empty);


            var attributes = s_attrReg.Matches(tagStr);

            // 剔除头

            foreach (Match match in attributes)
            {
                string str = match.Value;
                string key, value;
                int idx;
                if ((idx = str.IndexOf("=")) == -1)
                {
                    throw new TemplateEngineException("属性定义错误，错误信息：" + str);
                }

                key = str.Substring(0, idx).Trim();
                value = str.Substring(idx + 1, str.Length - idx - 1);
                value = value.Trim();

                // 剔除两边的引号
                value = value.Substring(1, value.Length - 2);
                _attributes.Add(key, value);
            }

            _result = this._innerStr;

            //替换后的字符串偏移量
            int offset = 0;
            foreach (var node in this.Nodes)
            {
                int start = (node.startNodeIdx - offset) - this.startNodeIdx - this.startNode.Length;
                //int end = (this.endNodeIdx + offset) - (node.endNodeIdx + node.endNode.Length);
                int end = (node.endNodeIdx + node.endNode.Length - offset) - this.startNodeIdx - this.startNode.Length;

                string str_start = this._result.Substring(0, start);
                string str_end = this._result.Substring(end, this._result.Length - end);

                string str_center = "{[" + node.NodeGuid.ToString("N") + "]}";
                offset += end - start - str_center.Length;

                _result = str_start + str_center + str_end;
            }

        }

        /// <summary>
        /// 翻译节点
        /// </summary>
        /// <returns>翻译后字符串</returns>
        internal string TranslateNode(XmlNode xmlNode)
        {
            TemplateLogger.LoadLogging("开始调用" + this._translate.GetType().Name + "接口Translate方法");
            string str = _translate.Translate(this, xmlNode);
            TemplateLogger.LoadLogging("结束调用" + this._translate.GetType().Name + "接口Translate方法");
            TemplateLogger.Debugger("执行结果:" + str);
            return str;
        }

    }
}
